設計理念:
Thread 導向的設計
為了降低複雜度,通常會採用 threads 導向的設計,把一個專案切分成比較易於管理的小塊(也就是 threads),而後每一個 thread 負責該應用程式的一部分。這樣的系統有助於識別 threads 之間的重要順序。也就是說,某些 threads 具有即時性的需求,必須盡量快速並且正確地回應它們。如果你的系統採用了專業的 RTOS,一定會有劃分 threads 優先權 (prioritization) 的設計。除了優先權之外,也會提供一套乾淨而且被仔細測試過的 API,有助於簡化 threads 之間的通訊。
所以如果我們採用 RTOS 的話,就會獲得一些工具能夠:
確保能夠在即時約束條件 (real-time constraints) 內執行時間關鍵 (time-critical) 部分的程式碼。或許同樣都很重要,但高優先權的 threads 所需要的即時行為,並不會受到低優先權 threads 的影響。
確保易於開發和維護複雜的應用。開發和維護小的 threads,比起硬搞整套應用更為容易。此外,對於低優先權 threads 的更動也不會影響到高優先權 threads 的即時處理。
能夠將整體應用程式的不同部分,分派給多個開發人員。每一個開發人員能夠擔負應用程式的一個或多個 threads,而且當他們在進行開發工作時,還會有一套乾淨的 API 能夠讓不同的 modules / threads 相互溝通。
採用 RTOS 的話,你不但能夠創建 threads,同時也具備一些讓它們能夠彼此溝通的工具,再加上能夠確保能夠在即時約束條件內執行完畢 threads 具時間關鍵的部分工作。由於採用了 RTOS,不同 threads 之間的介面將會變得非常乾淨,在進行開發的時候你就可以省時省力。
RTOS 如何工作?
RTOS 的核心被稱為 kernel,並提供有一個可以透過 kernel 去創建 threads 的 API。一個 thread 就像是一個擁有自己的堆疊、並帶有 Thread 控制區塊(TCB – Thread Control Block)的函式。除了 thread 本身私有的堆疊之外,每個 TCB 也保有一部分該 thread 的狀態訊息。
kernel 還包含有一個 scheuler,scheuler 會按照一套排程機制來執行 threads。各種 scheulers 之間主要的差異,就是如何分配執行他們所管理之各種 threads 的時間。基於優先權的 preemptive scheuler 是嵌入式 RTOS 之間最流行和普遍的 threads 調度演算法。通常情況下,相同優先權的 threads 會以 round-robin 循環的方式加以執行。
多數內核還會利用系統時脈 (system tick) 中斷,其典型的頻率為 10ms。如果在 RTOS 中缺乏系統時鐘,仍然能夠有某種基本形式的調度,但時間相關的服務則否。這種與時間有關的服務內容包括:軟體定時器、thread 睡眠 API 呼叫、thread 時間片段、以及逾時的 API 呼叫。
為了實現系統時脈中斷,可以透過嵌入式晶片的硬體計時器。大多數的 RTOS 有能力動態地擴增或重新設置計時器的中斷頻率,以便讓該系統進入睡眠,直到被下一個計時器期限或外部事件喚醒。例如,如果你有一個對耗能敏感的應用程式,您可能不希望每 10ms 就運行一次不必要的系統時脈處理程序。所以假設應用程式處於閒置狀態,想要把下一個定時器期限改為 1000ms。在這種情況下,計時器可以被重新規劃成 1000ms,應用程式則會進入低功耗模式。一旦在這種模式下,處理器將呈現休眠狀態,直到產生了外部事件、或是計時器的 1000ms 到期。在任一種情況之下,當處理器恢復執行時,RTOS 就會根據已經經過了多少時間來調整內部時間,並恢復 RTOS 和應用程式處理。如此一來,處理器只會在執行應用程式有事可做時進行運算。空閒期間處理器可以睡眠,並且節省電力。